package message

import (
	"encoding/binary"
	"gitee.com/zhongguo168a/go-nodex/nodex/enums/Serialize"
	"gitee.com/zhongguo168a/gocodes/datax"
	"gitee.com/zhongguo168a/gocodes/datax/binaryx"
	"gitee.com/zhongguo168a/gocodes/myx/errorx"
	"io"
)

// RequestMessage 请求消息
type RequestMessage struct {
	Seq uint32
	//
	SerializeMode Serialize.Mode
	//
	Route string //消息的ID
	// http模式需要每次请求都带上Token
	Token string
	//
	Data []byte
}

func (msg *RequestMessage) GetToken() string {
	return msg.Token
}

func (msg *RequestMessage) GetMsgID() string {
	return msg.Route
}

func (msg *RequestMessage) Unpack(reader io.Reader) error {
	if err := binary.Read(reader, binary.LittleEndian, &msg.Seq); err != nil {
		return errorx.Wrap(err, "read Seq")
	}
	if err := binary.Read(reader, binary.LittleEndian, &msg.SerializeMode); err != nil {
		return errorx.Wrap(err, "read SerializeMode")
	}
	if data, err := binaryx.ReadUTF(reader, binary.LittleEndian); err != nil {
		return errorx.Wrap(err, "read Token")
	} else {
		msg.Token = data
	}
	if data, err := binaryx.ReadUTF(reader, binary.LittleEndian); err != nil {
		return errorx.Wrap(err, "read Route")
	} else {
		msg.Route = data
	}

	if data, err := binaryx.ReadBytes(reader, binary.LittleEndian); err != nil {
		return errorx.Wrap(err, "read Route")
	} else {
		msg.Data = data
	}
	return nil
}

func (msg *RequestMessage) PackageLen() int {
	// seq + SerializeMode + Token + Route + Rows
	return 4 + 1 + (2 + len(msg.Token)) + (2 + len(msg.Route)) + (2 + len(msg.Data))
}

// Pack 封包方法(压缩数据)
func (msg *RequestMessage) Pack(writer io.Writer) error {
	if err := binary.Write(writer, binary.LittleEndian, int16(msg.PackageLen())); err != nil {
		return errorx.Wrap(err, "write PackageLen", datax.M{"PackageLen": msg.PackageLen()})
	}
	if err := binary.Write(writer, binary.LittleEndian, msg.Seq); err != nil {
		return errorx.Wrap(err, "write Seq", datax.M{"Seq": msg.Seq})
	}
	if err := binary.Write(writer, binary.LittleEndian, msg.SerializeMode); err != nil {
		return errorx.Wrap(err, "write SerializeMode", datax.M{"SerializeMode": msg.SerializeMode})
	}
	if err := binaryx.WriteUTF(writer, binary.LittleEndian, msg.Token); err != nil {
		return errorx.Wrap(err, "write Token", datax.M{"Token": msg.Token})
	}
	if err := binaryx.WriteUTF(writer, binary.LittleEndian, msg.Route); err != nil {
		return errorx.Wrap(err, "write Route", datax.M{"Route": msg.Route})
	}
	if err := binaryx.WriteBytes(writer, binary.LittleEndian, msg.Data); err != nil {
		return errorx.Wrap(err, "write Rows", datax.M{"Rows": msg.Route})
	}
	return nil
}
